using Microsoft.EntityFrameworkCore;
using MediPlatform.Infeartructure;
using Microsoft.Extensions.Logging;

namespace MediPlatform.Read.Api.Services
{
    /// <summary>
    /// 数据库初始化服务
    /// </summary>
    public class DatabaseInitializer
    {
        private readonly MyDbContext _context;
        private readonly ILogger<DatabaseInitializer> _logger;

        public DatabaseInitializer(MyDbContext context, ILogger<DatabaseInitializer> logger)
        {
            _context = context;
            _logger = logger;
        }

        /// <summary>
        /// 初始化数据库
        /// </summary>
        public async Task InitializeAsync()
        {
            try
            {
                _logger.LogInformation("开始初始化数据库...");

                // 确保数据库已创建（这将使用MySQL兼容的数据类型）
                bool created = await _context.Database.EnsureCreatedAsync();
                
                if (created)
                {
                    _logger.LogInformation("数据库已成功创建");
                }
                else
                {
                    _logger.LogInformation("数据库已存在，跳过创建步骤");
                    
                    // 如果需要，可以在这里执行数据库迁移
                    // await _context.Database.MigrateAsync();
                }

                _logger.LogInformation("数据库初始化完成");

                // 检查是否有用户数据，如果没有则创建默认管理员用户
                await CreateDefaultAdminUserAsync();
                
                // 创建测试用户数据
                await CreateTestUsersAsync();
                
                // 检查是否有退款申请数据，如果没有则创建测试数据
                await CreateTestRefundApplicationsAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据库初始化失败: {ErrorMessage}", ex.Message);
                if (ex.InnerException != null)
                {
                    _logger.LogError("内部异常: {InnerErrorMessage}", ex.InnerException.Message);
                }
                throw;
            }
        }

        /// <summary>
        /// 创建默认管理员用户
        /// </summary>
        private async Task CreateDefaultAdminUserAsync()
        {
            try
            {
                var userCount = await _context.User.CountAsync();
                if (userCount == 0)
                {
                    _logger.LogInformation("创建默认管理员用户...");

                    var adminUser = new MediPlatform.Domain.Order.User
                    {
                        UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0001",
                        Username = "admin",
                        Email = "admin@mediplatform.com",
                        PasswordHash = BCrypt.Net.BCrypt.HashPassword("admin123", BCrypt.Net.BCrypt.GenerateSalt(12)),
                        Role = "admin",
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    };

                    _context.User.Add(adminUser);
                    await _context.SaveChangesAsync();

                    _logger.LogInformation("默认管理员用户创建成功 - 用户名: admin, 密码: admin123");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建默认管理员用户失败");
            }
        }

        /// <summary>
        /// 创建测试用户数据
        /// </summary>
        private async Task CreateTestUsersAsync()
        {
            try
            {
                // 检查是否已经有测试用户
                var testUserCount = await _context.User.CountAsync(u => u.Username.StartsWith("test"));
                if (testUserCount == 0)
                {
                    _logger.LogInformation("创建测试用户数据...");

                    var testUsers = new List<MediPlatform.Domain.Order.User>
                    {
                        new MediPlatform.Domain.Order.User
                        {
                            UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0002",
                            Username = "testuser1",
                            Email = "test1@example.com",
                            PhoneNumber = "13800138001",
                            PasswordHash = BCrypt.Net.BCrypt.HashPassword("123456", BCrypt.Net.BCrypt.GenerateSalt(12)),
                            Role = "user",
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        },
                        new MediPlatform.Domain.Order.User
                        {
                            UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0003",
                            Username = "testuser2",
                            Email = "test2@example.com",
                            PhoneNumber = "13800138002",
                            PasswordHash = BCrypt.Net.BCrypt.HashPassword("123456", BCrypt.Net.BCrypt.GenerateSalt(12)),
                            Role = "user",
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        },
                        new MediPlatform.Domain.Order.User
                        {
                            UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0004",
                            Username = "testuser3",
                            Email = "test3@example.com",
                            PhoneNumber = "13800138003",
                            PasswordHash = BCrypt.Net.BCrypt.HashPassword("123456", BCrypt.Net.BCrypt.GenerateSalt(12)),
                            Role = "user",
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        },
                        new MediPlatform.Domain.Order.User
                        {
                            UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0005",
                            Username = "testuser4",
                            Email = "test4@example.com",
                            PhoneNumber = "13800138004",
                            PasswordHash = BCrypt.Net.BCrypt.HashPassword("123456", BCrypt.Net.BCrypt.GenerateSalt(12)),
                            Role = "user",
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        },
                        new MediPlatform.Domain.Order.User
                        {
                            UserId = "U" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "0006",
                            Username = "testuser5",
                            Email = "test5@example.com",
                            PhoneNumber = "13800138005",
                            PasswordHash = BCrypt.Net.BCrypt.HashPassword("123456", BCrypt.Net.BCrypt.GenerateSalt(12)),
                            Role = "user",
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        }
                    };

                    _context.User.AddRange(testUsers);
                    await _context.SaveChangesAsync();

                    _logger.LogInformation("测试用户数据创建成功，共创建 {Count} 个用户", testUsers.Count);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建测试用户数据失败");
            }
        }

        /// <summary>
        /// 创建退款申请测试数据
        /// </summary>
        private async Task CreateTestRefundApplicationsAsync()
        {
            try
            {
                var refundCount = await _context.RefundApplication.CountAsync();
                if (refundCount == 0)
                {
                    _logger.LogInformation("创建退款申请测试数据...");

                    // 获取测试用户ID
                    var testUsers = await _context.User.Where(u => u.Username.StartsWith("test")).ToListAsync();
                    if (testUsers.Count == 0)
                    {
                        _logger.LogWarning("没有找到测试用户，跳过创建退款申请测试数据");
                        return;
                    }

                    var testRefunds = new List<MediPlatform.Domain.Order.RefundApplication>
                    {
                        new MediPlatform.Domain.Order.RefundApplication
                        {
                            ApplicationNo = "RF202507310001",
                            OrderId = 1,
                            UserId = testUsers[0].Id,
                            Amount = 200.00m,
                            Status = 2, // 已拒绝
                            ApplyTime = DateTime.Now.AddDays(-2),
                            ProcessTime = DateTime.Now.AddDays(-1),
                            ProcessorId = testUsers[0].Id,
                            Remark = "测试退款申请1",
                            RefundChannel = "支付宝",
                            RefundType = "挂号预约",
                            ExtraInfo = "{\"reason\":\"患者取消预约\"}",
                            CreatedAt = DateTime.Now.AddDays(-2),
                            UpdatedAt = DateTime.Now.AddDays(-1)
                        },
                        new MediPlatform.Domain.Order.RefundApplication
                        {
                            ApplicationNo = "RF202507310002",
                            OrderId = 2,
                            UserId = testUsers.Count > 1 ? testUsers[1].Id : testUsers[0].Id,
                            Amount = 150.00m,
                            Status = 1, // 已处理
                            ApplyTime = DateTime.Now.AddDays(-3),
                            ProcessTime = DateTime.Now.AddDays(-2),
                            ProcessorId = testUsers[0].Id,
                            Remark = "测试退款申请2",
                            RefundChannel = "微信支付",
                            RefundType = "检查预约",
                            ExtraInfo = "{\"reason\":\"医生临时有事\"}",
                            CreatedAt = DateTime.Now.AddDays(-3),
                            UpdatedAt = DateTime.Now.AddDays(-2)
                        },
                        new MediPlatform.Domain.Order.RefundApplication
                        {
                            ApplicationNo = "RF202507310003",
                            OrderId = 3,
                            UserId = testUsers.Count > 2 ? testUsers[2].Id : testUsers[0].Id,
                            Amount = 300.00m,
                            Status = 0, // 待处理
                            ApplyTime = DateTime.Now.AddHours(-6),
                            ProcessTime = null,
                            ProcessorId = null,
                            Remark = null,
                            RefundChannel = "银行卡",
                            RefundType = "图文问诊",
                            ExtraInfo = "{\"reason\":\"系统故障\"}",
                            CreatedAt = DateTime.Now.AddHours(-6),
                            UpdatedAt = DateTime.Now.AddHours(-6)
                        },
                        new MediPlatform.Domain.Order.RefundApplication
                        {
                            ApplicationNo = "RF202507310004",
                            OrderId = 4,
                            UserId = testUsers.Count > 3 ? testUsers[3].Id : testUsers[0].Id,
                            Amount = 180.00m,
                            Status = 0, // 待处理
                            ApplyTime = DateTime.Now.AddHours(-2),
                            ProcessTime = null,
                            ProcessorId = null,
                            Remark = null,
                            RefundChannel = "支付宝",
                            RefundType = "视频问诊",
                            ExtraInfo = "{\"reason\":\"网络问题\"}",
                            CreatedAt = DateTime.Now.AddHours(-2),
                            UpdatedAt = DateTime.Now.AddHours(-2)
                        },
                        new MediPlatform.Domain.Order.RefundApplication
                        {
                            ApplicationNo = "RF202507310005",
                            OrderId = 5,
                            UserId = testUsers.Count > 4 ? testUsers[4].Id : testUsers[0].Id,
                            Amount = 250.00m,
                            Status = 1, // 已处理
                            ApplyTime = DateTime.Now.AddDays(-1),
                            ProcessTime = DateTime.Now.AddHours(-12),
                            ProcessorId = testUsers[0].Id,
                            Remark = "测试退款申请5",
                            RefundChannel = "微信支付",
                            RefundType = "电话问诊",
                            ExtraInfo = "{\"reason\":\"患者主动取消\"}",
                            CreatedAt = DateTime.Now.AddDays(-1),
                            UpdatedAt = DateTime.Now.AddHours(-12)
                        }
                    };

                    _context.RefundApplication.AddRange(testRefunds);
                    await _context.SaveChangesAsync();

                    _logger.LogInformation("退款申请测试数据创建成功，共创建 {Count} 条记录", testRefunds.Count);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建退款申请测试数据失败");
            }
        }
    }
} 